package org.uni_hi.muus.server.http;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;

import org.uni_hi.muus.server.util.HTTPServerCodes;
import org.uni_hi.muus.util.DateTimeFormatter;
import org.uni_hi.muus.util.StringUtil;

public class Response extends Header {

	public static final String
		FIELD_AGE="age",
		FIELD_ALLOW="allow",
		FIELD_ETAG="etag",
		FIELD_EXPIRES="expires",
		FIELD_LAST_MODIFIED="last-modified",
		FIELD_LOCATION="location",
		FIELD_PROXY_AUTHENTICATE="proxy-authenticate",
		FIELD_RETRY_AFTER="retry-after",
		FIELD_SERVER="server",
		FIELD_SET_COOKIE="set-cookie",
		FIELD_TRAILER="trailer",
		FIELD_TRANSFER_ENCODING="transfer-encoding",
		FIELD_VARY="vary",
		FIELD_WWW_AUTHENTICATE="www-authenticate";
	
	public static final String[] RESPONSE_FIELDS={
		FIELD_AGE,
		FIELD_ALLOW,
		FIELD_ETAG,
		FIELD_EXPIRES,
		FIELD_LAST_MODIFIED,
		FIELD_LOCATION,
		FIELD_PROXY_AUTHENTICATE,
		FIELD_RETRY_AFTER,
		FIELD_SERVER,
		FIELD_SET_COOKIE,
		FIELD_TRAILER,
		FIELD_TRANSFER_ENCODING,
		FIELD_VARY,
		FIELD_WWW_AUTHENTICATE};
	
	public Response(Request r){
		this(r._is,r._os);
		setStatusCode(r.getStatusCode(),r.getStatusExplanation());
	}
	
	public Response(DataInputStream is, PrintStream ps){
		super(StringUtil.CRLF,VALUE_SPLIT_TOKEN,is,ps);
		initResponse();
	}
	
	private void initResponse(){
		this.addValuePair(FIELD_SERVER, HTTPServerCodes.HTTP_SERVER_NAME);
		this.addValuePair(FIELD_DATE, DateTimeFormatter.getHTTPDateNow());
		this.addValuePair(FIELD_CONNECTION, "close");
	}

	public String toString(){
		return getCompleteHeader();
	}
	
	public String getCompleteHeader(){
		return (getResponseLine()+getHeaderLines());
	}
	
	public String getHeaderLines(){
		return printFields(RESPONSE_FIELDS)+super.toString();
	}

	public String getResponseLine() {
		return HTTPServerCodes.HTTP_VERSION+" "+HTTPServerCodes.getString4Code(getStatusCode())+StringUtil.CRLF;
	}
	
	public void setStatusCode(int code, String expl){
		super.setStatusCode(code, expl);
		setHeaderForStatus();
	}
	
	protected void setHeaderForStatus(){
		switch(getStatusCode()){
			case HTTPServerCodes.HTTP_CODE_401: addValuePair(FIELD_WWW_AUTHENTICATE, "Basic realm=\"Please Show Yourself To Be Worthy To Download!\"");
			case HTTPServerCodes.HTTP_CODE_405: addValuePair(FIELD_ALLOW, HTTPServerCodes.HTTP_GET+", "+HTTPServerCodes.HTTP_POST);
		}
	}

	public void returnResponse() {
		System.out.println("Returning response!");
		try {
			if(getStatusCode()>=400){
				String status=HTTPServerCodes.getString4Code(getStatusCode());
				status=HTTPServerCodes.getDoc4Stat(status,getStatusExplanation());
				_content=status.getBytes();
			}
			if(_content!=null){
				addValuePair(FIELD_CONTENT_LENGTH, Integer.toString(_content.length));
			}
			if(getStatusCode()==-1){
				setStatusCode(200, "");
			}
			System.out.print(getCompleteHeader());
			_os.print(getCompleteHeader());
			_os.println();
			if(_content!=null){
				_os.write(_content);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void setContent(byte[] bytes) {
		_content=bytes;
	}
}